package lv.solcraft.replication.server.scheduler;

import java.text.ParseException;

import lv.solcraft.replication.server.boot.ServerConfig;

import org.quartz.CronTrigger;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.SchedulerFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.util.Assert;

public class ServerScheduler implements ApplicationContextAware, InitializingBean, DisposableBean {

    private Scheduler scheduler;
    private ApplicationContext context;
    private ServerConfig serverConfig;

    public void setServerConfig(ServerConfig serverConfig) {
        this.serverConfig = serverConfig;
    }

    public void setApplicationContext(ApplicationContext context) throws BeansException {
        this.context = context;
    }

    public void afterPropertiesSet() throws Exception {
        SchedulerFactory schedulerFactory = new org.quartz.impl.StdSchedulerFactory();
        scheduler = schedulerFactory.getScheduler();
        scheduler.start();
        schedule();
    }

    private void schedule() throws ParseException, SchedulerException {
        Assert.notNull(context, "Application context is null");
        String[] beanNames = context.getBeanNamesForType(Scheduled.class);
        for (String beanName : beanNames) {
            Scheduled scheduledBean = (Scheduled) context.getBean(beanName);
            JobDetail jobDetail = new JobDetail();
            jobDetail.setName("job:" + beanName);
            jobDetail.setGroup("replication_server:" + serverConfig.getServerName());
            jobDetail.getJobDataMap().put(ScheduledExecutorJob.BEAN_NAME_PARAM, beanName);
            jobDetail.getJobDataMap().put(ScheduledExecutorJob.APPLICATION_CONTEXT_PARAM, context);
            jobDetail.setJobClass(ScheduledExecutorJob.class);
            CronTrigger trigger = new CronTrigger(serverConfig.getServerName() + "_Trigger_" + beanName, "replication");
            trigger.setCronExpression(scheduledBean.getCron());
            scheduler.scheduleJob(jobDetail, trigger);
        }
    }

    public void destroy() throws Exception {
        if (scheduler != null)
            scheduler.shutdown();
    }
}
